// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
//
// AES SBox testbench

module aes_sbox_tb #(
) (
  input  logic clk_i,
  input  logic rst_ni,

  output logic test_done_o,
  output logic test_passed_o
);

  import aes_pkg::*;

  logic [8:0] count_d, count_q;
  logic [7:0] stimulus;
  ciph_op_e   op;

  localparam int NUM_SBOX_IMPLS = 2;
  logic [7:0] responses[NUM_SBOX_IMPLS];

  // Generate the stimuli
  assign count_d = count_q + 9'h1;
  always_ff @(posedge clk_i or negedge rst_ni) begin : reg_count
    if (!rst_ni) begin
      count_q <= '0;
    end else begin
      count_q <= count_d;
    end
  end

  assign op = count_q[8] ? CIPH_FWD : CIPH_INV;
  assign stimulus = count_q[7:0];

  // Instantiate SBox Implementations
  aes_sbox #(
    .SBoxImpl ( "lut" )
  ) aes_sbox_lut (
    .op_i   ( op           ),
    .data_i ( stimulus     ),
    .data_o ( responses[0] )
  );

  aes_sbox #(
    .SBoxImpl ( "canright" )
  ) aes_sbox_canright (
    .op_i   ( op           ),
    .data_i ( stimulus     ),
    .data_o ( responses[1] )
  );

  // Check responses, signal end of simulation
  always_ff @(posedge clk_i or negedge rst_ni) begin : tb_ctrl
    test_done_o   <= 1'b0;
    test_passed_o <= 1'b1;

    for (int i=1; i<NUM_SBOX_IMPLS; i++) begin
      if (rst_ni && (responses[i] != responses[0])) begin
        $display("\nERROR: Mismatch between LUT-based S-Box and Implementation %0d found.", i);
        $display("op = %s, stimulus = 8'h%h, expected resp = 8'h%h, actual resp = 8'h%h\n",
            (op == CIPH_FWD) ? "CIPH_FWD" : "CIPH_INV", stimulus, responses[0], responses[1]);
        test_passed_o <= 1'b0;
        test_done_o   <= 1'b1;
      end
    end

    if (count_q == 9'h1FF) begin
      $display("\nSUCCESS: Outputs of all S-Box implementations match.");
      test_done_o <= 1'b1;
    end
  end

endmodule
